﻿using ARchGL.Platform.WindowsService.Core;
using ARchGL.Platform.WindowsService.Utils;
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;

namespace ARchGL.Platform.WindowsService.Application
{
    /// <summary>
    /// LED屏幕服务类
    /// </summary>
    public class LEDService : LEDBase
    {
        //每发送一条数据都需要
        //1.建立连接 
        //2.发送一次数据 
        //3.断开连接
        //不能建立连接，发送多次数据，断开连接（或不断开连接） 这样会在几天后出现显示异常

        private HardwareHelper hardwareHelper;

        public LEDService()
        {
            hardwareHelper = new HardwareHelper();
            UpdateConfig();
        }

        /// <summary>从服务端获取展示内容</summary>
        public ResultDto RequestContent()
        {
            //var url = "http://localhost:8100/api/services/huahui/ThirdParty/QueryProjectLEDInfo";
            var url = "http://hh.typeo.org/api/services/huahui/ThirdParty/QueryProjectLEDInfo";
            var hardwareJson = ",cpuId:\"" + hardwareHelper?.CpuID + "\",macAddress:\"" + hardwareHelper?.MacAddress + "\",diskId:\"" + hardwareHelper?.DiskID + "\"";
            var json = $"{{width:{width},heigh:{height},sectionNumber:{SectionNumber}{hardwareJson}}}";
            var data = Encoding.UTF8.GetBytes(json);
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/json";
            request.ContentLength = data.Length;

            using (var stream = request.GetRequestStream())
                stream.Write(data, 0, data.Length);

            using (var response = request.GetResponse() as HttpWebResponse)
            {
                if (response.StatusCode != HttpStatusCode.OK) return new ResultDto().GetDefault();

                // Get response  
                var content = string.Empty;
                using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    content = reader.ReadToEnd();

                return JsonConvert.DeserializeObject<ResultDto>(content);
            }
        }

        public void SendContent(string content)
        {
            SendContent(new ResultDto(content));
        }

        /// <summary>发送文字内容至 LED</summary>
        /// <param name="result"></param>
        public void SendContent(ResultDto result)
        {
            try
            {
                if (!User_RealtimeConnect(cardNumber))
                {
                    var asdfasd = cardNumber;
                    return; //连接实时通信失败
                }
                var title = result.Result.Title;

                SendText(result.Result.Content);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeConnect(); //断开连接
            }
        }

        /// <summary>发送图片至 LED</summary>
        public void SendBitmap(ResultDto result)
        {
            //var whiteBrush = new SolidBrush(Color.White); //白色笔
            var redBrush = new SolidBrush(Color.Red); //红色笔
            var blackBrush = new SolidBrush(Color.Black); //黑色笔（不显示，在有颜色的背景下可以显示）
            var fontBold = new Font("宋体", result.Result.TitleRectangle.FontSize);
            var fontRegular = new Font("宋体", result.Result.FontSize, FontStyle.Regular);

            try
            {
                if (!User_RealtimeConnect(cardNumber))
                {
                    var asdfasd = cardNumber;
                    return; //连接实时通信失败
                }

                var content = string.Empty;
                var majorList = new UserMajorsReportDto();
                if (result.Result.Content.Contains("{\""))
                    majorList = JsonConvert.DeserializeObject<UserMajorsReportDto>(result.Result.Content);
                else content = result.Result.Content;

                using (var bmp = new Bitmap(width, height))
                {
                    using (var g = Graphics.FromImage(bmp))
                    {
                        //1.设置整个画布，在画布上分左右显示内容
                        g.FillRectangle(blackBrush, 0, 0, width, height); //设置背景
                                                                          //g.FillRectangle(blackBrush, x + 1, y + 1, width - 2, heigh - 2);//设置背景，带边框线

                        //2.显示标题
                        var tr = result.Result.TitleRectangle;
                        var titleArea = new RectangleF(tr.X, tr.Y, tr.Width, tr.Height); //标题区域
                        g.DrawString(result.Result.Title, fontBold, redBrush, titleArea); //显示标题文字

                        //3.显示内容
                        var cr = result.Result.ContentRectangle;
                        if (string.IsNullOrEmpty(content))
                            for (int i = 0; i < majorList.MajorCount.Count; i++)
                            {
                                var item = majorList.MajorCount[i];
                                var width = majorList.GetGroupLength(i) * 18; //根据内容长度设置宽度

                                cr.Y = i % 2 == 0 ? 0 : 17;

                                var contentArea = new RectangleF(cr.X, cr.Y, width, cr.Height); //内容区域
                                g.DrawString(item.Name, fontBold, redBrush, contentArea); //显示内容文字

                                if (i % 2 != 0) cr.X += width; //将宽度加到 X 坐标上
                            }
                        else
                        {
                            if (content != "•")
                            {
                                var contentArea = new RectangleF(cr.X, cr.Y, width, cr.Height); //内容区域
                                g.DrawString(content, fontBold, redBrush, contentArea); //显示内容文字
                            }
                        }

                        if (GetScreen() == 0) //测试屏幕
                        {
                            var dateArea = new RectangleF(0, 32, width, 48); //内容区域
                            g.DrawString(DateTime.Now.ToString("HH:mm:ss"), fontRegular, redBrush, dateArea); //显示内容文字
                        }

                        //4.将画布发送至 LED 显示
                        var hbitmap = bmp.GetHbitmap();
                        if (!User_RealtimeSendData(cardNumber, 0, 0, width, height, hbitmap))
                        {
                            //lblMessage.Text = "实时发送图片1失败";
                        }
                        else
                        {
                            //lblMessage.Text = "实时发送图片1成功";
                        }
                        DeleteObject(hbitmap);
                    }
                }
            }
            catch (Exception ex)
            {
                SendText(ex.Message);
            }
            finally
            {
                DisposeConnect(); //断开连接

                redBrush.Dispose();
                blackBrush.Dispose();
                fontBold.Dispose();
                fontRegular.Dispose();
            }
        }

        public void DrawRectangleFloat(PaintEventArgs e)
        {
            // Create pen.
            var blackPen = new Pen(Color.Black, 3);

            // Create location and size of rectangle.
            float x = 0.0F;
            float y = 0.0F;
            float width = 200.0F;
            float height = 200.0F;

            // Draw rectangle to screen.
            e.Graphics.DrawRectangle(blackPen, x, y, width, height);
        }

        public void SendText(string content)
        {
            var fontInfo = new User_FontSet
            {
                bFontBold = false,
                bFontItaic = false,
                bFontUnderline = false,
                colorFont = 0xFFFF,
                iFontSize = 12,
                strFontName = "宋体",
                iAlignStyle = 0,
                iVAlignerStyle = 0,
                iRowSpace = 0
            };

            if (!User_RealtimeSendText(cardNumber, 0, 0, width, height, content, ref fontInfo))
            {
                //MessageBox.Show("发送实时文本失败！");
            }
            else
            {
                //MessageBox.Show("发送实时文本成功！");
            }
        }

        #region Private method

        /// <summary>更新 System32 下的配置文件</summary>
        private void UpdateConfig()
        {
            var sytem32path = Environment.GetFolderPath(Environment.SpecialFolder.System);
            var fileName = "/EQ2008_Dll_Set.ini";

            var binConfig = "." + fileName;
            if (!File.Exists(binConfig)) return;

            var binFile = File.GetLastWriteTime(binConfig);
            var sysFile = File.GetLastWriteTime(sytem32path + fileName);

            if (binFile != sysFile) File.Copy(binConfig, sytem32path + fileName, true);
        }

        #endregion
    }
}
